package com.web.exiaodao.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.web.exiaodao.business.entity.Category;
import com.web.exiaodao.business.entity.Shop;
import com.web.exiaodao.business.entity.ShopStandardName;
import com.web.exiaodao.business.entity.ShopStandardValues;
import com.web.exiaodao.business.repository.CategoryRepository;
import com.web.exiaodao.business.repository.ShopRepository;
import com.web.exiaodao.business.repository.ShopStandardNameRepository;
import com.web.exiaodao.business.repository.ShopStandardValuesRepository;
import com.web.exiaodao.business.service.ShopService;
import com.web.exiaodao.remote.vo.CategoryVo;
import com.web.exiaodao.remote.vo.ShopStandardNameVo;
import com.web.exiaodao.remote.vo.ShopStandardValuesVo;
import com.web.exiaodao.remote.vo.ShopVo;
import com.web.webstart.base.constant.XaConstant;
import com.web.webstart.base.exception.BaseException;
import com.web.webstart.base.exception.BusinessException;
import com.web.webstart.base.service.impl.BaseService;
import com.web.webstart.base.util.result.XaResult;
import com.web.webstart.base.util.XaUtil;
import com.web.webstart.base.util.jpa.DynamicSpecifications;
import com.web.webstart.base.util.jpa.MyPage;
import com.web.webstart.base.util.jpa.SearchFilter;
import com.web.webstart.base.util.jpa.SearchFilter.Operator;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("ShopService")
@Transactional(readOnly = false)
public class ShopServiceImpl extends BaseService<ShopVo> implements ShopService {

	private static final Logger LOGGER = Logger.getLogger(ShopServiceImpl.class);

	@Autowired
	private ShopRepository shopRepository;

    @Autowired
    private CategoryRepository shopCategoryRepository;

	@Autowired
	ShopStandardNameRepository standardRespository;

	@Autowired
	ShopStandardValuesRepository standardValuesRespository;

	/**
	 * 查询单条Shop信息
	 * //@param tId
	 * @return 返回单个Shop对象
	 * @throws BusinessException
	 */
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public XaResult<ShopVo> findOne(Long modelId) throws BusinessException {
	    throw new BusinessException(XaConstant.Message.error_method_no_impl);
	}

	/**
	 * 分页查询状态非status的Shop数据
	 * @param status
	 * @param filterParams
	 * @param pageable
	 * @return 返回对象Shop集合
	 * @throws BusinessException
	 */
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public XaResult<Page<ShopVo>> findListNEStatusByFilter(
			Integer status, Map<String, Object> filterParams, Pageable pageable) throws BusinessException {
		Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
		if(status == null){// 默认显示非删除的所有数据
			status = XaConstant.Status.delete;
		}
		filters.put("status", new SearchFilter("status", Operator.NE, status));
		Page<Shop> page = shopRepository.findAll(DynamicSpecifications
				.bySearchFilter(filters.values(), Shop.class), pageable);
		XaResult<Page<ShopVo>> xr = new XaResult<>();
        xr.setObject(new MyPage<>(page, JSON.parseArray(JSON.toJSONString(page.getContent()), ShopVo.class)));

        //查询分类信息
        Map<String, SearchFilter> categoryFilters = new HashMap<>();
        categoryFilters.put("status", filters.get("status"));
        List<Category> categories = shopCategoryRepository.findAll(DynamicSpecifications
                .bySearchFilter(categoryFilters.values(), Category.class));
        Map<String,Category> categoryMap = com.web.webstart.base.util.CollectionUtils.listToMap(categories != null ? categories.iterator() : null, new Function<Category, String>() {
            @Override
            public String apply(Category shopCategory) {
                return shopCategory.getId().toString();
            }
        });

        //拼装数据
        List<ShopVo> data = xr.getObject().getContent();
        for (int i = 0 ; categoryMap != null && data != null && i < data.size(); ++i) {
            long type =  data.get(i).getCategoryType();
            Category category = categoryMap.get(type+"");
            data.get(i).setShopCategoryVo(JSON.parseObject(JSON.toJSONString(category), CategoryVo.class));
        }
		LOGGER.info("后台----->分页查询实体集合（状态不等于）----->Shop");
		return xr;
	}

	/**
	 * 分页查询状态status的Shop数据
	 * @param status
	 * @param filterParams
	 * @param pageable
	 * @return 返回对象Shop集合
	 * @throws BusinessException
	 */
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public XaResult<Page<ShopVo>> findListEQStatusByFilter(
			Integer status, Map<String, Object> filterParams, Pageable pageable) throws BusinessException {
		Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
		if(status == null){// 默认显示正常数据
			status = XaConstant.Status.valid;
		}
		filters.put("status", new SearchFilter("status", Operator.EQ, status));
		Page<Shop> page = shopRepository.findAll(DynamicSpecifications
				.bySearchFilter(filters.values(), Shop.class), pageable);
		XaResult<Page<ShopVo>> xr = new XaResult<>();
        xr.setObject(new MyPage<>(page, JSON.parseArray(JSON.toJSONString(page.getContent()), ShopVo.class)));
		LOGGER.info("后台----->分页查询实体集合（状态等于）----->Shop");
		return xr;
	}


    /**
	 * 保存Shop信息
	 * @param model
	 * @return
	 * @throws BusinessException
	 */
	@Transactional(rollbackFor = Exception.class)
	public XaResult<ShopVo> saveOrUpdate(ShopVo model) throws BusinessException {
		throw new BusinessException(XaConstant.Message.error_method_no_impl);
	}

	/**
	 * 修改Shop状态，可一次修改多条   3删除  -1锁定  1正常
	 * //@param userId
	 * @param modelIds
	 * @param status
	 * @return 返回Shop对象
	 * @throws BusinessException
	 */
	@Transactional(rollbackFor = Exception.class)
	public XaResult<ShopVo> multiOperate(
			String modelIds,Integer status) throws BusinessException {
		XaResult<ShopVo> xr = new XaResult<>();
		if(status == null){
			status = XaConstant.Status.delete;
		}
		if(modelIds != null){
			String[] ids = modelIds.split(",");
			for(String id : ids){
				Shop obj = shopRepository.findByIdAndStatusNot(Long.parseLong(id),status);
				if (XaUtil.isNotEmpty(obj)) {
					obj.setStatus(status);
					obj = shopRepository.save(obj);
				}
			}
		}
		LOGGER.info("批量修改数据状态成功！");
		return xr;
	}

    @Override
    public XaResult<ShopVo> findShopById(Long tId) throws BusinessException {
        Shop obj = shopRepository.findByIdAndStatusNot(tId, XaConstant.Status.delete);
        XaResult<ShopVo> xr = new XaResult<ShopVo>();
        if (XaUtil.isNotEmpty(obj)) {
            List<ShopStandardName> stands = standardRespository.findByShopIdAndStatusNot(obj.getId() , XaConstant.Status.delete);

            //设置规格
            ShopVo shopVo = JSON.parseObject(JSON.toJSONString(obj), ShopVo.class);
            if (XaUtil.isNotEmpty(stands)) {
                shopVo = JSON.parseObject(JSON.toJSONString(obj), ShopVo.class);
                List<ShopStandardNameVo> standNames = new ArrayList<>();

                List<ShopStandardValues> values = standardValuesRespository.findByShopIdAndStatusNot(obj.getId(), XaConstant.Status.delete);
                for (int i = 0; i < stands.size(); ++i) {
                    ShopStandardName shopStandardName = stands.get(i);
                    ShopStandardNameVo shopStandardNameVo = JSON.parseObject(JSON.toJSONString(shopStandardName), ShopStandardNameVo.class);
                    ArrayList<ShopStandardValuesVo> shopStandardValuesVos = new ArrayList<>();
                    for (int j = 0; j < values.size(); ++j) {
                        if (NumberUtils.toLong(values.get(j).getShopStandsNameId()) == shopStandardName.getId()) {
                            shopStandardValuesVos.add(JSON.parseObject(JSON.toJSONString(values.get(j)), ShopStandardValuesVo.class));
                        }
                    }
                    shopStandardNameVo.setShopStandsValues(shopStandardValuesVos);
                    standNames.add(shopStandardNameVo);
                }
                shopVo.setStandards(standNames);
            }
            //设置分类
            Category category = shopCategoryRepository.findOne(obj.getCategoryType());
            shopVo.setShopCategoryVo(JSON.parseObject(JSON.toJSONString(category), CategoryVo.class));

            xr.setObject(shopVo);
            xr.getObject().setId(obj.getId());
            LOGGER.info("查询单个实体----->Shop");
        } else {
            xr.error(XaConstant.Message.object_not_find);
            LOGGER.info(XaConstant.Message.object_not_find);
            throw new BusinessException(XaConstant.Message.object_not_find);
        }
        return xr;
    }

	@Override
	public XaResult<Long> findShopCountByCategoryType(Long categoryType) throws BaseException {
		XaResult<Long> xr = new XaResult<>();
		long count =  shopRepository.findShopCountByCategoryIdAndStatusNot(categoryType, XaConstant.Status.delete);
		xr.setObject(count);
		return xr;
	}

	@Override
	public XaResult<ShopVo> createOrUpdateModelWithStandNames(Shop model, List<ShopStandardNameVo> shopStandardNameVos) throws BusinessException {
		XaResult<ShopVo> xr = new XaResult<ShopVo>();
		//1:保存商品
        Shop obj = null;
        if (XaUtil.isNotEmpty(model.getId())) {
            obj = shopRepository.findOne(model.getId());
            obj.setShopProductName(XaUtil.isNotEmpty(model.getShopProductName()) ? model.getShopProductName() : obj.getShopProductName());
            obj.setOriginalPrice(XaUtil.isNotEmpty(model.getOriginalPrice()) ? model.getOriginalPrice() : obj.getOriginalPrice());
            obj.setShopProductPrice(XaUtil.isNotEmpty(model.getShopProductPrice()) ? model.getShopProductPrice() : obj.getShopProductPrice());
            obj.setShopProductBrief(XaUtil.isNotEmpty(model.getShopProductBrief()) ? model.getShopProductBrief() : obj.getShopProductBrief());
            obj.setShopProductPicUrls(XaUtil.isNotEmpty(model.getShopProductPicUrls()) ? model.getShopProductPicUrls() : obj.getShopProductPicUrls());
            obj.setShopProductIntroduce(XaUtil.isNotEmpty(model.getShopProductIntroduce()) ? model.getShopProductIntroduce() : obj.getShopProductIntroduce());
            obj.setShopProductInventory(XaUtil.isNotEmpty(model.getShopProductInventory()) ? model.getShopProductInventory() : obj.getShopProductInventory());
            obj.setBrand(XaUtil.isNotEmpty(model.getBrand()) ? model.getBrand() : obj.getBrand());
            obj.setCategoryType(XaUtil.isNotEmpty(model.getCategoryType()) ? model.getCategoryType() : obj.getCategoryType());
            obj.setClickCont(XaUtil.isNotEmpty(model.getClickCont()) ? model.getClickCont() : obj.getClickCont());
            obj.setSort(XaUtil.isNotEmpty(model.getSort()) ? model.getSort() : obj.getSort());
            obj.setDiscountRate(XaUtil.isNotEmpty(model.getDiscountRate()) ? model.getDiscountRate() : obj.getDiscountRate());
        } else  {
			obj = model;
		}
		obj = shopRepository.save(obj);

		//2:保存规格-名称
		Long shopId = obj.getId();
        //保存规格前,要删掉该商品的规格
        if (XaUtil.isNotEmpty(shopId)) {
            int delStandardNameCount  = this.hsqlUpdate("DELETE FROM ShopStandardName   WHERE shopId = ?1",  Lists.newArrayList(shopId));
            int delStandardValueCount = this.hsqlUpdate("DELETE FROM ShopStandardValues WHERE shopId = ?1",  Lists.newArrayList(shopId));
        }

		for (int i = 0; i < shopStandardNameVos.size(); ++i) {
			ShopStandardNameVo ss = shopStandardNameVos.get(i);
			ss.setShopId(shopId);
		}
		java.lang.Iterable<ShopStandardName> standNames = standardRespository.save(JSON.parseArray(JSON.toJSONString(shopStandardNameVos), ShopStandardName.class));

		int ii = 0;
		for (ShopStandardName nameEn : standNames) {
			shopStandardNameVos.get(ii).setId(nameEn.getId());
			ii++;
		}

		//2:保存规格-值
		List<ShopStandardValuesVo> valueVos = new ArrayList<>();
		for (int j = 0; j < shopStandardNameVos.size(); ++j) {
			ShopStandardNameVo name = shopStandardNameVos.get(j);
			for (int k = 0; k < name.getShopStandsValues().size(); ++k) {
				ShopStandardValuesVo value = name.getShopStandsValues().get(k);
				value.setShopStandsNameId(name.getId());
				value.setShopId(obj.getId());
			}
			valueVos.addAll(name.getShopStandsValues());
		}
		java.lang.Iterable<ShopStandardValues> values = standardValuesRespository.save(JSON.parseArray(JSON.toJSONString(valueVos), ShopStandardValues.class));

		//拼凑规格和规格值
		List<ShopStandardNameVo> nameVoList = new ArrayList<>();
		for (ShopStandardName nameTemp : standNames) {
			ShopStandardNameVo nameTempVo = JSON.parseObject(JSON.toJSONString(nameTemp), ShopStandardNameVo.class);
			for (ShopStandardValues valueTemp : values) {
				if (Long.parseLong(valueTemp.getShopStandsNameId()) == nameTempVo.getId()) {
					nameTempVo.getShopStandsValues().add(JSON.parseObject(JSON.toJSONString(valueTemp), ShopStandardValuesVo.class));
				}
			}
			nameVoList.add(nameTempVo);
		}

		//设置规格和规格值
		ShopVo shopVo = JSON.parseObject(JSON.toJSONString(obj), ShopVo.class);
		shopVo.setStandards(nameVoList);

		//设置分类
		Category category = shopCategoryRepository.findOne(model.getCategoryType());
		shopVo.setShopCategoryVo(JSON.parseObject(JSON.toJSONString(category), CategoryVo.class));

		xr.setObject(shopVo);
		xr.getObject().setId(obj.getId());
		LOGGER.info("新增数据成功----->Shop");
		return xr;
	}
}
